#ifndef _BASE_SERVICE_H_
#define _BASE_SERVICE_H_

#include "IoSocketExManager.h"
#include "AccepterEx.h"
#include "ConnectorEx.h"
#include "IoServiceExPool.h"
#include "IPacketParser.h"

template<typename TSession, typename TRpcSession, typename TPacketParser>
class CBaseService
{
public:
    CBaseService(TPacketParser &parser, s32 connCount, s32 szSend, s32 szRecv, s32 rpcConnCount, s32 rpcSzSend, s32 rpcSzRecv, s32 ioServiceCount, bool useEventWorker=false, s32 workerCount=0, s32 evtQueueSize=0) : 
        m_connCount( connCount ),
        m_szSend( szSend ),
        m_szRecv( szRecv ),
        m_ioSocketMgr( parser ),
        m_rpcConnCount( rpcConnCount ),
        m_rpcSzSend( rpcSzSend ),
        m_rpcSzRecv( rpcSzRecv ),
        m_ioRpcSocketMgr( parser ),
        m_ioSerivcePool( ioServiceCount, useEventWorker, workerCount, evtQueueSize ), 
        m_accepter( m_ioSerivcePool, m_ioSocketMgr ),
        m_connector( m_ioSerivcePool, m_ioRpcSocketMgr )
    {
    }

    bool Start(s32 port)
    {
        // Session
        {
            TSession ioSocket(0);
            SGLib::CIoSocketEx *ptest = ioSocket.Clone( 0 );
            if( !ptest )
            {
                return false;
            }
            SAFE_DELETE( ptest );

            if( !m_ioSocketMgr.Init( m_connCount, m_szSend, m_szRecv, ioSocket ) )
            {
                return false;
            }
        }

        // RPC Session
        {
            TRpcSession ioSocket(0);
            SGLib::CIoSocketEx *ptest = ioSocket.Clone( 0 );
            if( !ptest )
            {
                return false;
            }
            SAFE_DELETE( ptest );

            if( !m_ioRpcSocketMgr.Init( m_rpcConnCount, m_rpcSzSend, m_rpcSzRecv, ioSocket ) )
            {
                return false;
            }
        }

        return ( m_ioSerivcePool.Start() && 
                m_connector.Start() &&
                m_accepter.Start(port) );
    }

    void Stop()
    {
        m_connector.Stop();
        m_accepter.Stop();
        m_ioSerivcePool.Stop();
    }

    void Connect(const char *ip, s32 port, UserData *ud)
    {
        m_connector.Connect( ip, port, ud );
    }

	SGLib::CIoServiceExPool& GetIoServiceExPool()
	{
		return m_ioSerivcePool;
	} 
    
    SGLib::IPacketParser* GetPacketParser()
    {
        return m_ioSocketMgr.GetPacketParser();
    }

private:
    s32 m_connCount;
    s32 m_szSend;
    s32 m_szRecv;
    SGLib::CIoSocketExMgr m_ioSocketMgr;

    s32 m_rpcConnCount;
    s32 m_rpcSzSend;
    s32 m_rpcSzRecv;
    SGLib::CIoSocketExMgr m_ioRpcSocketMgr;

    SGLib::CIoServiceExPool m_ioSerivcePool;
    SGLib::CAccepterEx m_accepter;
    SGLib::CConnectorEx m_connector;
};


#endif

